#ifndef DIRECTORIO_H_
#define DIRECTORIO_H_

#include "../../Constantes.h"
#include "../../FuncionesUtiles.h"
#include "Hash.h"

#include <iostream>
using namespace std;

class RecursoDeAlmacenamientoDirecto;
class Bucket;
class Key;
class Elemento;
class TipoClave;

class Directorio {

	friend class Bucket;

private:
	RecursoDeAlmacenamientoDirecto* archivoDirectorio;
	RecursoDeAlmacenamientoDirecto* archivoBuckets;
	cantBytes profundidad;
	cantBytes tamanioBucket;

	TipoClave* extractor;
	offset* direcciones;
	Bucket* bucketActual;
	cantBytes nroCeldas;

	Hash hash;

public:

	/*
	 * Pre: -
	 * Pos: Crea una nueva instancia.
	 */
	Directorio(cantBytes tamanioBucket, string path,TipoClave* extractor);

		/*
	 * Pre: -
	 * Pos: configura el archivo.
	 */
	void crearOLevantar(const string &path);

	/*
	 * Pre: -
	 * Pos: Libera los recursos instanciados.
	 */
	virtual ~Directorio();

	/*
	 * Pre: -
	 * Pos: setea el elemento.
	 */
	bool obtenerElemento(Key &clave,Elemento &elemento);

	/*
	 * Pre: la clave del elemento no exista
	 * Pos: inserta el elemento.
	 */
	bool insertar(Elemento &elemento);

	/*
	 * Pre: -
	 * Pos: borra la clave del directorio.
	 */
	bool borrar(Key &clave, offset& numComponente);

	/*
	 * Pre: -
	 * Pos: duplica el tamanio del Directorio.
	 */
	bool duplicarTamanio();

	/*
	 * Pre: -
	 * Pos: divide el tamanio del directorio.
	 */
	bool reducirTamanio();

	/*
	 * Pre: -
	 * Pos: Imprime el directorio.
	 */

	void imprimirDirectorio();

	/*
	 * Pre: -
	 * Pos: devuelve si la clave se encuentra almacenada.
	 */
	bool seEncuentraAlmacenada(Key &clave);

private:

	/*
	 * Pre: -
	 * Pos: carga el bucket relacionado con la clave.
	 */
	void cargarBucket(Key &clave);

	/*
	 * Pre: -
	 * Pos: devuelve el offset del bucket.
	 */
	offset obtenerDireccionBucket(Key &clave, offset profundidad);

	/*
	 * Pre: -
	 * Pos: guarda los cambios del bucket.
	 */
	bool guardarBucket(Bucket *bucket);

	/*
	 * Pre: -
	 * Pos: inserta el bucket en el directorio.
	 */
	bool insertarBucket(Bucket *bucket,offset inicial, offset final);

	/*
	 * Pre: -
	 * Pos: setea la profundidad del directorio.
	 */
	void setProfundidad(offset profundidad);

	/*
	 * Pre: Archivo correcto
	 * Pos: Obtiene el bucket del archivo.
	 */
	Bucket* obtenerBucketdeArchivo(offset nroComponente);

};

#endif /* DIRECTORIO_H_ */
